#include <gtest/gtest.h>
#include "viml/garbage_collector.h"
#include "viml/types.h"

using namespace viml;

class GarbageCollectorTest : public ::testing::Test {
protected:
    void SetUp() override;
    void TearDown() override;

    std::unique_ptr<GarbageCollector> gc_;
    std::unique_ptr<GCRootSet> root_set_;
};

TEST_F(GarbageCollectorTest, BasicGCFunctionality) {
    // 测试垃圾回收器的基本功能
    gc_ = std::make_unique<GarbageCollector>();
    root_set_ = std::make_unique<GCRootSet>();
    gc_->set_root_set(root_set_.get());
}

TEST_F(GarbageCollectorTest, ObjectManagement) {
    // 测试对象添加和管理
    gc_ = std::make_unique<GarbageCollector>();
    root_set_ = std::make_unique<GCRootSet>();
    gc_->set_root_set(root_set_.get());

    // 测试添加对象
    auto test_obj1 = std::make_unique<Object>(ObjectHeader::Type::STRING);
    auto test_obj2 = std::make_unique<Object>(ObjectHeader::Type::LIST);
    auto test_obj3 = std::make_unique<Object>(ObjectHeader::Type::DICT);

    gc_->add_object(test_obj1.get());
    gc_->add_object(test_obj2.get());
    gc_->add_object(test_obj3.get());

    // 验证对象计数
    EXPECT_EQ(test_obj1->get_ref_count(), 1);
    EXPECT_EQ(test_obj2->get_ref_count(), 1);
    EXPECT_EQ(test_obj3->get_ref_count(), 1);

    // 验证分代
    EXPECT_EQ(gc_->get_object_generation(test_obj1.get()), GarbageCollector::Generation::YOUNG);
    EXPECT_EQ(gc_->get_object_generation(test_obj2.get()), GarbageCollector::Generation::YOUNG);
    EXPECT_EQ(gc_->get_object_generation(test_obj3.get()), GarbageCollector::Generation::YOUNG);
}

TEST_F(GarbageCollectorTest, RootSetManagement) {
    // 测试根集合管理
    gc_ = std::make_unique<GarbageCollector>();
    root_set_ = std::make_unique<GCRootSet>();
    gc_->set_root_set(root_set_.get());

    // 测试根集大小
    EXPECT_EQ(root_set_->size(), 0);

    // 测试添加根对象
    auto root_obj = std::make_unique<Object>(ObjectHeader::Type::STRING);
    root_set_->add_root(root_obj.get());
    EXPECT_EQ(root_set_->size(), 1);

    // 测试添加值对象
    auto test_list = std::make_unique<ListObject>();
    auto dict_obj = std::make_unique<DictObject>();
    // 简化：这里需要实现ListObject和DictObject
    root_set_->add_value_root(Value(test_list));
    root_set_->add_value_root(Value(dict_obj));

    EXPECT_EQ(root_set_->size(), 3); // 1个字符串对象 + 1个列表对象 + 1个字典对象

    // 测试清空根集
    root_set_->clear_roots();
    EXPECT_EQ(root_set_->size(), 0);
}

TEST_F(GarbageCollectorTest, CollectionProcess) {
    // 测试垃圾回收过程
    gc_ = std::make_unique<GarbageCollector>();
    root_set_ = std::make_unique<GCRootSet>();
    gc_->set_root_set(root_set_.get());

    // 添加一些对象
    auto obj1 = std::make_unique<Object>(ObjectHeader::Type::STRING);
    auto obj2 = std::make_unique<Object>(ObjectHeader::Type::LIST);
    auto obj3 = std::make_unique<Object>(ObjectHeader::Type::DICT);

    gc_->add_object(obj1.get());
    gc_->add_object(obj2.get());
    gc_->add_object(obj3.get());

    // 记录初始统计
    auto stats_before = gc_->get_stats();
    EXPECT_EQ(stats_before.total_objects, 3);

    // 设置禁用状态以确保只测试基本功能
    gc_->set_enabled(false);

    // 手动触发垃圾回收（应该不执行任何操作）
    auto result_disabled = gc_->collect();
    EXPECT_EQ(result_disabled.objects_collected, 0);
    EXPECT_EQ(result_disabled.collection_time_ms, 0.0);

    // 启用垃圾回收
    gc_->set_enabled(true);

    // 手动触发垃圾回收
    auto result = gc_->collect();

    // 验证垃圾回收结果
    EXPECT_GT(result.collection_time_ms, 0.0);
    EXPECT_GE(result.objects_collected, 0);

    // 验证统计信息更新
    auto stats_after = gc_->get_stats();
    EXPECT_GT(stats_after.total_objects, stats_before.total_objects); // 应该回收一些对象
    EXPECT_EQ(stats_after.total_collections, stats_before.total_collections + 1);
    EXPECT_EQ(stats_after.total_bytes_allocated, stats_before.total_bytes_allocated);
    EXPECT_GT(stats_after.total_bytes_freed, 0);
    EXPECT_GT(stats_after.average_collection_time_ms, 0.0);
}

TEST_F(GarbageCollectorTest, GenerationalPromotion) {
    // 测试分代晋升功能
    gc_ = std::make_unique<GarbageCollector>();
    root_set_ = std::make_unique<GCRootSet>();
    gc_->set_root_set(root_set_.get());

    // 添加大量年轻代对象
    for (int i = 0; i < 20; ++i) {
        gc_->add_object(std::make_unique<Object>(ObjectHeader::Type::YOUNG));
    }

    auto stats_before = gc_->get_stats();
    EXPECT_EQ(stats_before.total_objects, 20);

    // 触发多次垃圾回收（模拟对象老化）
    for (int i = 0; i < 5; ++i) {
        auto result = gc_->collect();
        // 每次回收后都应该有一些对象被回收
        EXPECT_GT(result.objects_collected, 0);
        EXPECT_GT(result.young_gen_collected, 0);
    }

    auto stats_after = gc_->get_stats();
    EXPECT_LT(stats_after.total_objects, stats_before.total_objects); // 应该回收了一些对象
    EXPECT_GT(stats_after.total_collections, 5);
}

TEST_F(GarbageCollectorTest, GCStatsAndReporting) {
    // 测试统计信息和报告
    gc_ = std::make_unique<GarbageCollector>();
    root_set_ = std::make_unique<GCRootSet>();
    gc_->set_root_set(root_set_.get());

    // 测试初始统计
    auto initial_stats = gc_->get_stats();
    EXPECT_EQ(initial_stats.total_objects, 0);
    EXPECT_EQ(initial_stats.total_collections, 0);
    EXPECT_EQ(initial_stats.total_bytes_allocated, 0);

    // 添加对象并测试统计更新
    gc_->add_object(std::make_unique<Object>(ObjectHeader::Type::STRING));
    auto updated_stats = gc_->get_stats();
    EXPECT_EQ(updated_stats.total_objects, 1);
    EXPECT_GT(updated_stats.total_bytes_allocated, 0);

    // 重置统计
    gc_->reset_stats();
    auto reset_stats = gc_->get_stats();
    EXPECT_EQ(reset_stats.total_objects, 0);
    EXPECT_EQ(reset_stats.total_collections, 0);
    EXPECT_EQ(reset_stats.total_bytes_allocated, 0);
}

TEST_F(GarbageCollectorTest, ThreadSafetyAndGlobalManagement) {
    // 测试全局GC管理器的线程安全性
    root_set_ = std::make_unique<GCRootSet>();
    gc_->set_root_set(root_set_.get());

    // 获取多个实例（应该返回相同的实例）
    auto& gc1 = GCManager::get_instance();
    auto& gc2 = GCManager::get_instance();

    EXPECT_EQ(&gc1, &gc2); // 应该是同一个实例

    // 测试禁用功能
    GCManager::disable();
    EXPECT_FALSE(gc1.is_enabled());
    EXPECT_FALSE(gc2.is_enabled());

    // 重新启用
    GCManager::enable();
    EXPECT_TRUE(gc1.is_enabled());
    EXPECT_TRUE(gc2.is_enabled());

    // 测试全局统计
    GCManager::reset_global_stats();
    auto stats_before = GCManager::get_global_stats();
    EXPECT_EQ(stats_before.total_objects, 0);

    gc_->add_object(std::make_unique<Object>(ObjectHeader::Type::STRING));
    auto result = GCManager::collect_garbage();

    auto stats_after = GCManager::get_global_stats();
    EXPECT_EQ(stats_after.total_objects, stats_before.total_objects - 1); // 应该被回收了1个对象
}

TEST_F(GarbageCollectorTest, PerformanceCharacteristics) {
    // 测试垃圾回收器的性能特征
    gc_ = std::make_unique<GarbageCollector>();
    root_set_ = std::make_unique<GCRootSet>();
    gc_->set_root_set(root_set_.get());

    // 创建大量对象进行性能测试
    const int NUM_OBJECTS = 100;
    for (int i = 0; i < NUM_OBJECTS; ++i) {
        gc_->add_object(std::make_unique<Object>(ObjectHeader::Type::YOUNG));
    }

    auto stats = gc_->get_stats();
    EXPECT_EQ(stats.total_objects, NUM_OBJECTS);

    // 重置GC并测试清理性能
    gc_->set_enabled(false);

    // 触发回收并测量时间
    auto start_time = std::chrono::high_resolution_clock::now();
    auto result = gc_->collect();
    auto end_time = std::chrono::high_resolution_clock::now();
    auto collection_time = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count();

    std::cout << "性能测试 - 回收了 " << result.objects_collected
              << " 个对象，耗时 " << collection_time << "ms" << std::endl;
}

    // 验证性能指标
    EXPECT_GT(result.collection_time_ms, 0.0);
    EXPECT_GT(result.objects_collected, 0);
}